﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package org.nickro.project.BulkLoad {
    import flash.display.*;
    import flash.media.*;
    import flash.events.*;
    import org.nickro.project.BulkLoad.loadingtypes.*;
    import flash.net.*;
    import flash.utils.*;

    public class BulkLoader extends EventDispatcher {

        public static const CAN_BEGIN_PLAYING:String = "canBeginPlaying";
        public static const TYPE_VIDEO:String = "video";
        public static const PREVENT_CACHING:String = "preventCache";
        public static const TYPE_TEXT:String = "text";
        public static const ID:String = "id";
        public static const PAUSED_AT_START:String = "pausedAtStart";
        public static const SECURITY_ERROR:String = "securityError";
        public static const LOG_WARNINGS:int = 3;
        public static const PROGRESS:String = "progress";
        public static const COMPLETE:String = "complete";
        public static const AVAILABLE_TYPES:Array = [TYPE_VIDEO, TYPE_XML, TYPE_TEXT, TYPE_SOUND, TYPE_MOVIECLIP, TYPE_IMAGE, TYPE_BINARY];
        public static const LOG_VERBOSE:int = 0;
        public static const OPEN:String = "open";
        public static const HEADERS:String = "headers";
        public static const TYPE_XML:String = "xml";
        public static const HTTP_STATUS:String = "httpStatus";
        public static const CONTEXT:String = "context";
        public static const WEIGHT:String = "weight";
        public static const CHECK_POLICY_FILE:String = "checkPolicyFile";
        public static const TYPE_MOVIECLIP:String = "movieclip";
        public static const PRIORITY:String = "priority";
        public static const TYPE_BINARY:String = "binary";
        public static const TYPE_SOUND:String = "sound";
        public static const MAX_TRIES:String = "maxTries";
        public static const VERSION:String = "$Id: BulkLoader.as 316 2010-01-29 01:30:10Z debert $";
        public static const GENERAL_AVAILABLE_PROPS:Array = [WEIGHT, MAX_TRIES, HEADERS, ID, PRIORITY, PREVENT_CACHING, "type"];
        public static const DEFAULT_NUM_CONNECTIONS:int = 12;
        public static const LOG_SILENT:int = 10;
        public static const ERROR:String = "error";
        public static const LOG_INFO:int = 2;
        public static const DEFAULT_LOG_LEVEL:int = 4;
        public static const LOG_ERRORS:int = 4;
        public static const TYPE_IMAGE:String = "image";

        public static var MOVIECLIP_EXTENSIONS:Array = ["swf"];
        public static var XML_EXTENSIONS:Array = ["xml"];
        public static var SOUND_EXTENSIONS:Array = ["mp3", "f4a", "f4b"];
        public static var TEXT_EXTENSIONS:Array = ["txt", "js", "php", "asp", "py"];
        public static var AVAILABLE_EXTENSIONS:Array = ["swf", "jpg", "jpeg", "gif", "png", "flv", "mp3", "xml", "txt", "js"];
        public static var _allLoaders:Object = {};
        public static var VIDEO_EXTENSIONS:Array = ["flv", "f4v", "f4p", "mp4"];
        public static var IMAGE_EXTENSIONS:Array = ["jpg", "jpeg", "gif", "png"];
        public static var _customTypesExtensions:Object;
        public static var _typeClasses:Object = {
            image:ImageItem,
            movieclip:ImageItem,
            xml:XMLItem,
            video:VideoItem,
            sound:SoundItem,
            text:URLItem,
            binary:BinaryItem
        };
        public static var _instancesCreated:int = 0;

        public var _itemsTotal:int = 0;
        public var speedAvg:Number;
        public var _numConnections:int = 12;
        public var _totalWeight:int = 0;
        public var _bytesTotalCurrent:int = 0;
        public var _itemsLoaded:int = 0;
        public var totalTime:Number;
        public var _additionIndex:int = 0;
        public var _bytesTotal:int = 0;
        public var _loadedRatio:Number = 0;
        public var _speed:Number;
        public var _lastSpeedCheck:int;
        public var _isPaused:Boolean = true;
        public var _isFinished:Boolean;
        public var _name:String;
        public var _allowsAutoIDFromFileName:Boolean = false;
        public var _contents:Dictionary;
        public var _logFunction:Function;
        public var _bytesLoaded:int = 0;
        public var _connections:Object;
        public var logLevel:int = 4;
        public var _percentLoaded:Number = 0;
        public var _weightPercent:Number;
        public var _lastBytesCheck:int;
        public var _isRunning:Boolean;
        public var _id:int;
        public var _items:Array;
        public var _stringSubstitutions:Object;
        public var avgLatency:Number;
        public var _startTime:int;
        public var maxConnectionsPerHost:int = 2;
        public var _speedTotal:Number;
        public var _endTIme:int;

        public function BulkLoader(_arg1:String=null, _arg2:int=12, _arg3:int=4){
            this._items = [];
            this._contents = new Dictionary(true);
            this._logFunction = trace;
            super();
            if (!_arg1){
                _arg1 = getUniqueName();
            };
            if (Boolean(_allLoaders[_arg1])){
                __debug_print_loaders();
                throw (new Error((("BulkLoader with name'" + _arg1) + "' has already been created.")));
            };
            if (!_arg1){
                throw (new Error("Cannot create a BulkLoader instance without a name"));
            };
            _allLoaders[_arg1] = this;
            if (_arg2 > 0){
                this._numConnections = _arg2;
            };
            this.logLevel = _arg3;
            this._name = _arg1;
            _instancesCreated++;
            this._id = _instancesCreated;
            this._additionIndex = 0;
            addEventListener(BulkLoader.ERROR, this._swallowError, false, 1, true);
        }
        public static function getLoader(_arg1:String):BulkLoader{
            return ((BulkLoader._allLoaders[_arg1] as BulkLoader));
        }
        public static function whichLoaderHasItem(_arg1):BulkLoader{
            var _local2:BulkLoader;
            for each (_local2 in _allLoaders) {
                if (BulkLoader._hasItemInBulkLoader(_arg1, _local2)){
                    return (_local2);
                };
            };
            return (null);
        }
        public static function truncateNumber(_arg1:Number, _arg2:int=2):Number{
            var _local3:int = Math.pow(10, _arg2);
            return ((Math.round((_arg1 * _local3)) / _local3));
        }
        public static function __debug_printStackTrace():void{
            try {
                throw (new Error("stack trace"));
            } catch(e:Error) {
                trace(e.getStackTrace());
            };
        }
        public static function __debug_print_loaders():void{
            var instNames:* = null;
            var theNames:* = [];
            for each (instNames in BulkLoader._allLoaders) {
                theNames.push(instNames);
            };
            theNames.sort();
            trace("All loaders");
            theNames.forEach(function (_arg1, ... _args):void{
                trace("\t", _arg1);
            });
            trace("===========");
        }
        public static function pauseAllLoaders():void{
            var _local1:BulkLoader;
            for each (_local1 in _allLoaders) {
                _local1.pauseAll();
            };
        }
        public static function _hasItemInBulkLoader(_arg1, _arg2:BulkLoader):Boolean{
            var _local3:LoadingItem = _arg2.get(_arg1);
            if (((_local3) && (_local3._isLoaded))){
                return (true);
            };
            return (false);
        }
        public static function createUniqueNamedLoader(_arg1:int=12, _arg2:int=4):BulkLoader{
            return (new BulkLoader(BulkLoader.getUniqueName(), _arg1, _arg2));
        }
        public static function removeAllLoaders():void{
            var _local1:BulkLoader;
            for each (_local1 in _allLoaders) {
                _local1.removeAll();
                _local1.clear();
                _local1 = null;
            };
            _allLoaders = {};
        }
        public static function getFileName(_arg1:String, _arg2:Boolean=false):String{
            if (_arg1.lastIndexOf("/") == (_arg1.length - 1)){
                return (getFileName(_arg1.substring(0, (_arg1.length - 1))));
            };
            var _local3:int = (_arg1.lastIndexOf("/") + 1);
            var _local4:String = _arg1.substring(_local3);
            var _local5:int = (_arg2) ? _local4.length : _local4.indexOf(".");
            if (_local5 == -1){
                if (_local4.indexOf("?") > -1){
                    _local5 = _local4.indexOf("?");
                } else {
                    _local5 = _local4.length;
                };
            };
            var _local6:String = _local4.substring(0, _local5);
            return (_local6);
        }
        public static function __debug_print_num_loaders():void{
            var _local2:String;
            var _local1:int;
            for each (_local2 in BulkLoader._allLoaders) {
                _local1++;
            };
            trace("BulkLoader has ", _local1, "instances");
        }
        public static function guessType(_arg1:String):String{
            var _local5:String;
            var _local6:String;
            var _local7:String;
            var _local2:String = ((_arg1.indexOf("?") > -1)) ? _arg1.substring(0, _arg1.indexOf("?")) : _arg1;
            var _local3:String = _local2.substring(_local2.lastIndexOf("/"));
            var _local4:String = _local3.substring((_local3.lastIndexOf(".") + 1)).toLowerCase();
            if (!Boolean(_local4)){
                _local4 = BulkLoader.TYPE_TEXT;
            };
            if ((((_local4 == BulkLoader.TYPE_IMAGE)) || ((BulkLoader.IMAGE_EXTENSIONS.indexOf(_local4) > -1)))){
                _local5 = BulkLoader.TYPE_IMAGE;
            } else {
                if ((((_local4 == BulkLoader.TYPE_SOUND)) || ((BulkLoader.SOUND_EXTENSIONS.indexOf(_local4) > -1)))){
                    _local5 = BulkLoader.TYPE_SOUND;
                } else {
                    if ((((_local4 == BulkLoader.TYPE_VIDEO)) || ((BulkLoader.VIDEO_EXTENSIONS.indexOf(_local4) > -1)))){
                        _local5 = BulkLoader.TYPE_VIDEO;
                    } else {
                        if ((((_local4 == BulkLoader.TYPE_XML)) || ((BulkLoader.XML_EXTENSIONS.indexOf(_local4) > -1)))){
                            _local5 = BulkLoader.TYPE_XML;
                        } else {
                            if ((((_local4 == BulkLoader.TYPE_MOVIECLIP)) || ((BulkLoader.MOVIECLIP_EXTENSIONS.indexOf(_local4) > -1)))){
                                _local5 = BulkLoader.TYPE_MOVIECLIP;
                            } else {
                                for (_local6 in _customTypesExtensions) {
                                    for each (_local7 in _customTypesExtensions[_local6]) {
                                        if (_local7 == _local4){
                                            _local5 = _local6;
                                            break;
                                        };
                                        if (_local5){
                                            break;
                                        };
                                    };
                                };
                                if (!_local5){
                                    _local5 = BulkLoader.TYPE_TEXT;
                                };
                            };
                        };
                    };
                };
            };
            return (_local5);
        }
        public static function registerNewType(_arg1:String, _arg2:String, _arg3:Class=null):Boolean{
            var _local4:Array;
            if (_arg1.charAt(0) == "."){
                _arg1 = _arg1.substring(1);
            };
            if (!_customTypesExtensions){
                _customTypesExtensions = {};
            };
            _arg2 = _arg2.toLowerCase();
            if (AVAILABLE_TYPES.indexOf(_arg2) == -1){
                if (!Boolean(_arg3)){
                    throw (new Error("[BulkLoader]: When adding a new type and extension, you must determine which class to use"));
                };
                _typeClasses[_arg2] = _arg3;
                if (!_customTypesExtensions[_arg2]){
                    _customTypesExtensions[_arg2] = [];
                    AVAILABLE_TYPES.push(_arg2);
                };
                _customTypesExtensions[_arg2].push(_arg1);
                return (true);
            };
            if (_customTypesExtensions[_arg2]){
                _customTypesExtensions[_arg2].push(_arg1);
            };
            var _local5:Object = {};
            _local5[TYPE_IMAGE] = IMAGE_EXTENSIONS;
            _local5[TYPE_MOVIECLIP] = MOVIECLIP_EXTENSIONS;
            _local5[TYPE_VIDEO] = VIDEO_EXTENSIONS;
            _local5[TYPE_SOUND] = SOUND_EXTENSIONS;
            _local5[TYPE_TEXT] = TEXT_EXTENSIONS;
            _local5[TYPE_XML] = XML_EXTENSIONS;
            _local4 = _local5[_arg2];
            if (((_local4) && ((_local4.indexOf(_arg1) == -1)))){
                _local4.push(_arg1);
                return (true);
            };
            return (false);
        }
        public static function substituteURLString(_arg1:String, _arg2:Object):String{
            var _local9:Object;
            var _local10:Object;
            var _local12:String;
            if (!_arg2){
                return (_arg1);
            };
            var _local3:RegExp = /(?P<var_name>\{\s*[^\}]*\})/g;
            var _local4:Object = _local3.exec(_arg1);
            var _local5:String = (_local4) ? _local4.var_name : null;
            var _local6:Array = [];
            var _local7:int;
            while (((Boolean(_local4)) && (Boolean(_local4.var_name)))) {
                if (_local4.var_name){
                    _local5 = _local4.var_name;
                    _local5 = _local5.replace("{", "");
                    _local5 = _local5.replace("}", "");
                    _local5 = _local5.replace(/\s*/g, "");
                };
                _local6.push({
                    start:_local4.index,
                    end:(_local4.index + _local4.var_name.length),
                    changeTo:_arg2[_local5]
                });
                _local7++;
                if (_local7 > 400){
                    break;
                };
                _local4 = _local3.exec(_arg1);
                _local5 = (_local4) ? _local4.var_name : null;
            };
            if (_local6.length == 0){
                return (_arg1);
            };
            var _local8:Array = [];
            var _local11:String = _arg1.substr(0, _local6[0].start);
            for each (_local10 in _local6) {
                if (_local9){
                    _local11 = _arg1.substring(_local9.end, _local10.start);
                };
                _local8.push(_local11);
                _local8.push(_local10.changeTo);
                _local9 = _local10;
            };
            _local8.push(_arg1.substring(_local10.end));
            return (_local8.join(""));
        }
        public static function getUniqueName():String{
            return (("BulkLoader-" + _instancesCreated));
        }

        public function get allowsAutoIDFromFileName():Boolean{
            return (this._allowsAutoIDFromFileName);
        }
        public function _onItemComplete(_arg1:Event):void{
            var _local2:LoadingItem = (_arg1.target as LoadingItem);
            this._removeFromConnections(_local2);
            this.log("Loaded ", _local2, LOG_INFO);
            this.log("Items to load", this.getNotLoadedItems(), LOG_VERBOSE);
            _local2.cleanListeners();
            this._contents[_local2.url.url] = _local2.content;
            var _local3:Boolean = this._loadNext();
            var _local4:Boolean = this._isAllDoneP();
            if (_local4){
                this._onAllLoaded();
            };
            _arg1.stopPropagation();
        }
        public function get loadedRatio():Number{
            return (this._loadedRatio);
        }
        public function loadNow(_arg1):Boolean{
            var _local3:LoadingItem;
            var _local2:LoadingItem = this.get(_arg1);
            if (!_local2){
                return (false);
            };
            if (!this._connections){
                this._connections = {};
            };
            if ((((_local2.status == LoadingItem.STATUS_FINISHED)) || ((_local2.status == LoadingItem.STATUS_STARTED)))){
                return (true);
            };
            if ((((this._getNumConnections() >= this.numConnections)) || ((this._getNumConnectionsForItem(_local2) >= this.maxConnectionsPerHost)))){
                _local3 = this._getLeastUrgentOpenedItem();
                this.pause(_local3);
                this._removeFromConnections(_local3);
                _local3.status = null;
            };
            _local2._priority = this.highestPriority;
            this._loadNext(_local2);
            return (true);
        }
        public function set allowsAutoIDFromFileName(_arg1:Boolean):void{
            this._allowsAutoIDFromFileName = _arg1;
        }
        public function _getContentAsType(_arg1, _arg2:Class, _arg3:Boolean=false){
            var res:* = undefined;
            var key:* = _arg1;
            var type:* = _arg2;
            var clearMemory:Boolean = _arg3;
            if (!this._name){
                throw (new Error("[BulkLoader] Cannot use an instance that has been cleared from memory (.clear())"));
            };
            var item:* = this.get(key);
            if (!item){
                return (null);
            };
            try {
                if (((item._isLoaded) || (((item.isStreamable()) && ((item.status == LoadingItem.STATUS_STARTED)))))){
                    res = (item.content as type);
                    if (res == null){
                        throw (new Error("bad cast"));
                    };
                    if (clearMemory){
                        this.remove(key);
                        if (!this._isPaused){
                            this._loadNext();
                        };
                    };
                    return (res);
                };
            } catch(e:Error) {
                log((("Failed to get content with url: '" + key) + "'as type:"), type, LOG_ERRORS);
            };
            return (null);
        }
        public function set stringSubstitutions(_arg1:Object):void{
            this._stringSubstitutions = _arg1;
        }
        public function get contents():Object{
            return (this._contents);
        }
        public function get id():int{
            return (this._id);
        }
        public function _getConnectionsForHostName(_arg1:String):Array{
            if (this._connections[_arg1] == null){
                this._connections[_arg1] = [];
            };
            return (this._connections[_arg1]);
        }
        public function getBitmap(_arg1:String, _arg2:Boolean=false):Bitmap{
            return (Bitmap(this._getContentAsType(_arg1, Bitmap, _arg2)));
        }
        public function _removeFromConnections(_arg1):Boolean{
            if (((!(this._connections)) || ((this._getNumConnectionsForItem(_arg1) == 0)))){
                return (false);
            };
            var _local2:Array = this._getConnectionsForHostName(_arg1.hostName);
            var _local3:int = _local2.indexOf(_arg1);
            if (_local3 > -1){
                _local2.splice(_local3, 1);
                return (true);
            };
            return (false);
        }
        public function resume(_arg1):Boolean{
            var _local2:LoadingItem = ((_arg1 is LoadingItem)) ? _arg1 : this.get(_arg1);
            this._isPaused = false;
            if (((_local2) && ((_local2.status == LoadingItem.STATUS_STOPPED)))){
                _local2.status = null;
                this._loadNext();
                return (true);
            };
            return (false);
        }
        public function _onAllLoaded():void{
            if (this._isFinished){
                return;
            };
            var _local1:BulkProgressEvent = new BulkProgressEvent(COMPLETE);
            _local1.setInfo(this.bytesLoaded, this.bytesTotal, this.bytesTotalCurrent, this._itemsLoaded, this.itemsTotal, this.weightPercent);
            var _local2:BulkProgressEvent = new BulkProgressEvent(PROGRESS);
            _local2.setInfo(this.bytesLoaded, this.bytesTotal, this.bytesTotalCurrent, this._itemsLoaded, this.itemsTotal, this.weightPercent);
            this._isRunning = false;
            this._endTIme = getTimer();
            this.totalTime = BulkLoader.truncateNumber(((this._endTIme - this._startTime) / 1000));
            this._updateStats();
            this._connections = {};
            this.getStats();
            this._isFinished = true;
            this.log("Finished all", LOG_INFO);
            dispatchEvent(_local2);
            dispatchEvent(_local1);
        }
        public function removePausedItems():Boolean{
            var stoppedLoads:* = this._items.filter(function (_arg1:LoadingItem, ... _args):Boolean{
                return ((_arg1.status == LoadingItem.STATUS_STOPPED));
            });
            stoppedLoads.forEach(function (_arg1:LoadingItem, ... _args):void{
                remove(_arg1);
            });
            this._loadNext();
            return ((stoppedLoads.length > 0));
        }
        public function resumeAll():Boolean{
            this.log("Resuming all items", LOG_VERBOSE);
            var affected:* = false;
            this._items.forEach(function (_arg1:LoadingItem, ... _args):void{
                if (_arg1.status == LoadingItem.STATUS_STOPPED){
                    resume(_arg1);
                    affected = true;
                };
            });
            this._loadNext();
            return (affected);
        }
        public function get isRunning():Boolean{
            return (this._isRunning);
        }
        public function _getNumConnectionsForItem(_arg1:LoadingItem):int{
            var _local2:Array = this._getConnectionsForHostName(_arg1.hostName);
            if (!_local2){
                return (0);
            };
            return (_local2.length);
        }
        public function getProgressForItems(_arg1:Array):BulkProgressEvent{
            var _local11:LoadingItem;
            var _local13:*;
            this._bytesLoaded = (this._bytesTotal = (this._bytesTotalCurrent = 0));
            var _local2:Number = 0;
            var _local3:int;
            var _local4:int;
            var _local5:Number = 0;
            var _local6:int;
            var _local7:int;
            var _local8:int;
            var _local9:int;
            var _local10:int;
            var _local12:Array = [];
            for each (_local13 in _arg1) {
                _local11 = this.get(_local13);
                if (!_local11){
                } else {
                    _local6++;
                    _local3 = (_local3 + _local11.weight);
                    if ((((((_local11.status == LoadingItem.STATUS_STARTED)) || ((_local11.status == LoadingItem.STATUS_FINISHED)))) || ((_local11.status == LoadingItem.STATUS_STOPPED)))){
                        _local8 = (_local8 + _local11._bytesLoaded);
                        _local10 = (_local10 + _local11._bytesTotal);
                        if (_local11._bytesTotal > 0){
                            _local5 = (_local5 + ((_local11._bytesLoaded / _local11._bytesTotal) * _local11.weight));
                        };
                        if (_local11.status == LoadingItem.STATUS_FINISHED){
                            _local7++;
                        };
                        _local4++;
                    };
                };
            };
            if (_local4 != _local6){
                _local9 = Number.POSITIVE_INFINITY;
            } else {
                _local9 = _local10;
            };
            _local2 = (_local5 / _local3);
            if (_local3 == 0){
                _local2 = 0;
            };
            var _local14:BulkProgressEvent = new BulkProgressEvent(PROGRESS);
            _local14.setInfo(_local8, _local9, _local9, _local7, _local6, _local2);
            return (_local14);
        }
        public function get logFunction():Function{
            return (this._logFunction);
        }
        public function getNetStreamMetaData(_arg1:String, _arg2:Boolean=false):Object{
            var _local3:NetStream = this.getNetStream(_arg1, _arg2);
            return ((Boolean(_local3)) ? (this.get(_arg1) as Object).metaData : null);
        }
        public function getContent(_arg1:String, _arg2:Boolean=false){
            return (this._getContentAsType(_arg1, Object, _arg2));
        }
        public function getSerializedData(_arg1, _arg2:Boolean=false, _arg3:Function=null){
            var raw:* = undefined;
            var parsed:* = undefined;
            var key:* = _arg1;
            var clearMemory:Boolean = _arg2;
            var encodingFunction = _arg3;
            try {
                raw = this._getContentAsType(key, Object, clearMemory);
                parsed = encodingFunction.apply(null, [raw]);
                return (parsed);
            } catch(e:Error) {
                log("Failed to parse key:", key, ("with encodingFunction:" + encodingFunction), LOG_ERRORS);
            };
            return (null);
        }
        public function log(... _args):void{
            var _local2:int = (isNaN(_args[(_args.length - 1)])) ? 3 : int(_args.pop());
            if (_local2 >= this.logLevel){
                this._logFunction(("[BulkLoader] " + _args.join(" ")));
            };
        }
        public function clear():void{
            this.removeAll();
            delete _allLoaders[this.name];
            this._name = null;
        }
        public function get speed():Number{
            var _local1:int = (getTimer() - this._lastSpeedCheck);
            var _local2:int = ((this.bytesLoaded - this._lastBytesCheck) / 0x0400);
            var _local3:int = (_local2 / (_local1 / 1000));
            this._lastSpeedCheck = _local1;
            this._lastBytesCheck = this.bytesLoaded;
            return (_local3);
        }
        public function get bytesLoaded():int{
            return (this._bytesLoaded);
        }
        public function getFailedItems():Array{
            return (this._items.filter(function (_arg1:LoadingItem, ... _args):Boolean{
                return ((_arg1.status == LoadingItem.STATUS_ERROR));
            }));
        }
        public function _loadNext(_arg1:LoadingItem=null):Boolean{
            var _local3:Array;
            if (this._isFinished){
                return (false);
            };
            if (!this._connections){
                this._connections = {};
            };
            var _local2:Boolean;
            _arg1 = ((_arg1) || (this._getNextItemToLoad()));
            if (_arg1){
                _local2 = true;
                this._isRunning = true;
                if (this._canOpenConnectioForItem(_arg1)){
                    _local3 = this._getConnectionsForHostName(_arg1.hostName);
                    _local3.push(_arg1);
                    _arg1.load();
                    this.log("Will load item:", _arg1, LOG_INFO);
                };
                if (this._getNextItemToLoad()){
                    this._loadNext();
                };
            };
            return (_local2);
        }
        public function getSound(_arg1, _arg2:Boolean=false):Sound{
            return (Sound(this._getContentAsType(_arg1, Sound, _arg2)));
        }
        public function removeFailedItems():int{
            var numCleared:* = 0;
            var badItems:* = this._items.filter(function (_arg1:LoadingItem, ... _args):Boolean{
                return ((_arg1.status == LoadingItem.STATUS_ERROR));
            });
            numCleared = badItems.length;
            badItems.forEach(function (_arg1:LoadingItem, ... _args):void{
                remove(_arg1);
            });
            this._loadNext();
            return (numCleared);
        }
        public function get(_arg1):LoadingItem{
            var _local2:LoadingItem;
            if (!_arg1){
                return (null);
            };
            if ((_arg1 is LoadingItem)){
                return (_arg1);
            };
            for each (_local2 in this._items) {
                if ((((((((_local2._id == _arg1)) || ((_local2._parsedURL.rawString == _arg1)))) || ((_local2.url == _arg1)))) || ((((_arg1 is URLRequest)) && ((_local2.url.url == _arg1.url)))))){
                    return (_local2);
                };
            };
            return (null);
        }
        public function _getNumConnections():int{
            var _local2:String;
            var _local1:int;
            for (_local2 in this._connections) {
                _local1 = (_local1 + this._connections[_local2].length);
            };
            return (_local1);
        }
        public function get highestPriority():int{
            var _local2:LoadingItem;
            var _local1:int = int.MIN_VALUE;
            for each (_local2 in this._items) {
                if (_local2.priority > _local1){
                    _local1 = _local2.priority;
                };
            };
            return (_local1);
        }
        public function start(_arg1:int=-1):void{
            if (_arg1 > 0){
                this._numConnections = _arg1;
            };
            if (this._connections){
                this._loadNext();
                return;
            };
            this._startTime = getTimer();
            this._connections = {};
            this._loadNext();
            this._isRunning = true;
            this._lastBytesCheck = 0;
            this._lastSpeedCheck = getTimer();
            this._isPaused = false;
        }
        public function _getAllConnections():Array{
            var _local2:String;
            var _local1:Array = [];
            for (_local2 in this._connections) {
                _local1 = _local1.concat(this._connections[_local2]);
            };
            return (_local1);
        }
        public function _getLeastUrgentOpenedItem():LoadingItem{
            var _local1:Array = this._getAllConnections();
            _local1.sortOn(["priority", "bytesRemaining", "_additionIndex"], [Array.NUMERIC, Array.DESCENDING, Array.NUMERIC, Array.NUMERIC]);
            var _local2:LoadingItem = LoadingItem(_local1[0]);
            return (_local2);
        }
        public function getBitmapData(_arg1, _arg2:Boolean=false):BitmapData{
            var key:* = _arg1;
            var clearMemory:Boolean = _arg2;
            try {
                return (this.getBitmap(key, clearMemory).bitmapData);
            } catch(e:Error) {
                log("Failed to get bitmapData with url:", key, LOG_ERRORS);
            };
            return (null);
        }
        public function set logFunction(_arg1:Function):void{
            this._logFunction = _arg1;
        }
        override public function toString():String{
            return (((((("[BulkLoader] name:" + this.name) + ", itemsTotal: ") + this.itemsTotal) + ", itemsLoaded: ") + this._itemsLoaded));
        }
        public function get itemsTotal():int{
            return (this.items.length);
        }
        public function sortItemsByPriority():void{
            this._items.sortOn(["priority", "_additionIndex"], [(Array.NUMERIC | Array.DESCENDING), Array.NUMERIC]);
        }
        public function get stringSubstitutions():Object{
            return (this._stringSubstitutions);
        }
        public function _swallowError(_arg1:Event):void{
        }
        public function get name():String{
            return (this._name);
        }
        public function remove(_arg1, _arg2:Boolean=false):Boolean{
            var item:* = null;
            var allDone:* = false;
            var key:* = _arg1;
            var internalCall:Boolean = _arg2;
            try {
                item = this.get(key);
                if (!item){
                    return (false);
                };
                this._removeFromItems(item);
                this._removeFromConnections(item);
                item.destroy();
                delete this._contents[item.url.url];
                if (internalCall){
                    return (true);
                };
                item = null;
                this._onProgress();
                allDone = this._isAllDoneP();
                if (allDone){
                    this._onAllLoaded();
                };
                return (true);
            } catch(e:Error) {
                log(("Error while removing item from key:" + key), e.getStackTrace(), LOG_ERRORS);
            };
            return (false);
        }
        public function removeAll():void{
            var _local1:LoadingItem;
            for each (_local1 in this._items.slice()) {
                this.remove(_local1, true);
            };
            this._items = [];
            this._connections = {};
            this._contents = new Dictionary(true);
            this._percentLoaded = (this._weightPercent = (this._loadedRatio = 0));
        }
        public function _updateStats():void{
            var _local4:LoadingItem;
            this.avgLatency = 0;
            this.speedAvg = 0;
            var _local1:Number = 0;
            var _local2:int;
            this._speedTotal = 0;
            var _local3:Number = 0;
            for each (_local4 in this._items) {
                if (((_local4._isLoaded) && (!((_local4.status == LoadingItem.STATUS_ERROR))))){
                    _local1 = (_local1 + _local4.latency);
                    _local2 = (_local2 + _local4.bytesTotal);
                    _local3++;
                };
            };
            this._speedTotal = ((_local2 / 0x0400) / this.totalTime);
            this.avgLatency = (_local1 / _local3);
            this.speedAvg = (this._speedTotal / _local3);
        }
        public function reload(_arg1):Boolean{
            var _local2:LoadingItem = this.get(_arg1);
            if (!_local2){
                return (false);
            };
            this._removeFromItems(_local2);
            this._removeFromConnections(_local2);
            _local2.stop();
            _local2.cleanListeners();
            _local2.status = null;
            this._isFinished = false;
            _local2._addedTime = getTimer();
            _local2._additionIndex = this._additionIndex++;
            _local2.addEventListener(Event.COMPLETE, this._onItemComplete, false, int.MIN_VALUE, true);
            _local2.addEventListener(Event.COMPLETE, this._incrementItemsLoaded, false, int.MAX_VALUE, true);
            _local2.addEventListener(ERROR, this._onItemError, false, 0, true);
            _local2.addEventListener(Event.OPEN, this._onItemStarted, false, 0, true);
            _local2.addEventListener(ProgressEvent.PROGRESS, this._onProgress, false, 0, true);
            this._items.push(_local2);
            this._itemsTotal = (this._itemsTotal + 1);
            this._totalWeight = (this._totalWeight + _local2.weight);
            this.sortItemsByPriority();
            this._isFinished = false;
            this.loadNow(_local2);
            return (true);
        }
        public function _onItemStarted(_arg1:Event):void{
            var _local2:LoadingItem = (_arg1.target as LoadingItem);
            this.log("Started loading", _local2, LOG_INFO);
            dispatchEvent(_arg1);
        }
		//添加文件列表:
        public function add(_arg1, _arg2:Object=null):LoadingItem{
            var _local4:String;
            var _local6:String;
            if (!this._name){
                throw (new Error("[BulkLoader] Cannot use an instance that has been cleared from memory (.clear())"));
            };
            if (((!(_arg1)) || (!(String(_arg1))))){
                throw (new Error("[BulkLoader] Cannot add an item with a null url"));
            };
            _arg2 = ((_arg2) || ({}));
            if ((_arg1 is String)){
                _arg1 = new URLRequest(BulkLoader.substituteURLString(_arg1, this._stringSubstitutions));
                if (_arg2[HEADERS]){
                    _arg1.requestHeaders = _arg2[HEADERS];
                };
            } else {
                if ((!(_arg1) is URLRequest)){
                    throw (new Error(("[BulkLoader] cannot add object with bad type for url:'" + _arg1.url)));
                };
            };
            var _local3:LoadingItem = this.get(_arg2[ID]);
            if (_local3){
                this.log((("Add received an already added id: " + _arg2[ID]) + ", not adding a new item"));
                return (_local3);
            };
            if (_arg2["type"]){
                _local4 = _arg2["type"].toLowerCase();
                if (AVAILABLE_TYPES.indexOf(_local4) == -1){
                    this.log("add received an unknown type:", _local4, "and will cast it to text", LOG_WARNINGS);
                };
            };
            if (!_local4){
                _local4 = guessType(_arg1.url);
            };
            this._additionIndex++;
            _local3 = new _typeClasses[_local4](_arg1, _local4, ((_instancesCreated + "_") + String(this._additionIndex)));
            if (((!(_arg2["id"])) && (this._allowsAutoIDFromFileName))){
                _arg2["id"] = getFileName(_arg1.url);
                this.log("Adding automatic id from file name for item:", _local3, (("( id= " + _arg2["id"]) + " )"));
            };
            var _local5:Array = _local3._parseOptions(_arg2);
            for each (_local6 in _local5) {
                this.log(_local6, LOG_WARNINGS);
            };
            this.log("Added", _local3, LOG_VERBOSE);
            _local3._addedTime = getTimer();
            _local3._additionIndex = this._additionIndex;
			
			//加载
            _local3.addEventListener(Event.COMPLETE, this._onItemComplete, false, int.MIN_VALUE, true);
            _local3.addEventListener(Event.COMPLETE, this._incrementItemsLoaded, false, int.MAX_VALUE, true);
            _local3.addEventListener(ERROR, this._onItemError, false, 0, true);
            _local3.addEventListener(Event.OPEN, this._onItemStarted, false, 0, true);
            _local3.addEventListener(ProgressEvent.PROGRESS, this._onProgress, false, 0, true);
						
            this._items.push(_local3);
            this._itemsTotal = (this._itemsTotal + 1);
            this._totalWeight = (this._totalWeight + _local3.weight);
            this.sortItemsByPriority();
            this._isFinished = false;
            if (!this._isPaused){
                this._loadNext();
            };
            return (_local3);
        }
        public function getText(_arg1, _arg2:Boolean=false):String{
            return (String(this._getContentAsType(_arg1, String, _arg2)));
        }
        public function get percentLoaded():Number{
            return (this._percentLoaded);
        }
        public function get weightPercent():Number{
            return (this._weightPercent);
        }
        public function get bytesTotalCurrent():int{
            return (this._bytesTotalCurrent);
        }
        public function getAVM1Movie(_arg1:String, _arg2:Boolean=false):AVM1Movie{
            return (AVM1Movie(this._getContentAsType(_arg1, AVM1Movie, _arg2)));
        }
        public function get bytesTotal():int{
            return (this._bytesTotal);
        }
        public function getSprite(_arg1:String, _arg2:Boolean=false):Sprite{
            return (Sprite(this._getContentAsType(_arg1, Sprite, _arg2)));
        }
        public function get isFinished():Boolean{
            return (this._isFinished);
        }
        public function _getNextItemToLoad():LoadingItem{
            var checkItem:* = null;
            this._getAllConnections().forEach(function (_arg1:LoadingItem, ... _args):void{
                if ((((_arg1.status == LoadingItem.STATUS_ERROR)) && ((_arg1.numTries >= _arg1.maxTries)))){
                    _removeFromConnections(_arg1);
                };
            });
            for each (checkItem in this._items) {
                if (((((!(checkItem._isLoading)) && (!((checkItem.status == LoadingItem.STATUS_STOPPED))))) && (this._canOpenConnectioForItem(checkItem)))){
                    return (checkItem);
                };
            };
            return (null);
        }
        public function changeItemPriority(_arg1:String, _arg2:int):Boolean{
            var _local3:LoadingItem = this.get(_arg1);
            if (!_local3){
                return (false);
            };
            _local3._priority = _arg2;
            this.sortItemsByPriority();
            return (true);
        }
        public function get items():Array{
            return (this._items.slice());
        }
        public function getNetStream(_arg1:String, _arg2:Boolean=false):NetStream{
            return (NetStream(this._getContentAsType(_arg1, NetStream, _arg2)));
        }
        public function getHttpStatus(_arg1):int{
            var _local2:LoadingItem = this.get(_arg1);
            if (_local2){
                return (_local2.httpStatus);
            };
            return (-1);
        }
        public function set itemsLoaded(_arg1:int):void{
            this._itemsLoaded = _arg1;
        }
        public function _onProgress(_arg1:Event=null):void{
            var _local2:BulkProgressEvent = this.getProgressForItems(this._items);
            this._bytesLoaded = _local2.bytesLoaded;
            this._bytesTotal = _local2.bytesTotal;
            this._weightPercent = _local2.weightPercent;
            this._percentLoaded = _local2.percentLoaded;
            this._bytesTotalCurrent = _local2.bytesTotalCurrent;
            this._loadedRatio = _local2.ratioLoaded;
            dispatchEvent(_local2);
        }
        public function hasItem(_arg1, _arg2:Boolean=true):Boolean{
            var _local3:*;
            var _local4:BulkLoader;
            if (_arg2){
                _local3 = _allLoaders;
            } else {
                _local3 = [this];
            };
            for each (_local4 in _local3) {
                if (_hasItemInBulkLoader(_arg1, _local4)){
                    return (true);
                };
            };
            return (false);
        }
        public function _removeFromItems(_arg1:LoadingItem):Boolean{
            var _local2:int = this._items.indexOf(_arg1);
            if (_local2 > -1){
                this._items.splice(_local2, 1);
            } else {
                return (false);
            };
            if (_arg1._isLoaded){
                this._itemsLoaded--;
            };
            this._itemsTotal--;
            this._totalWeight = (this._totalWeight - _arg1.weight);
            this.log(("Removing " + _arg1), LOG_VERBOSE);
            _arg1.removeEventListener(Event.COMPLETE, this._onItemComplete, false);
            _arg1.removeEventListener(Event.COMPLETE, this._incrementItemsLoaded, false);
            _arg1.removeEventListener(ERROR, this._onItemError, false);
            _arg1.removeEventListener(Event.OPEN, this._onItemStarted, false);
            _arg1.removeEventListener(ProgressEvent.PROGRESS, this._onProgress, false);
            return (true);
        }
        public function _incrementItemsLoaded(_arg1:Event):void{
            this._itemsLoaded++;
        }
        public function _getNumConnectionsForHostname(_arg1:String):int{
            var _local2:Array = this._getConnectionsForHostName(_arg1);
            if (!_local2){
                return (0);
            };
            return (_local2.length);
        }
        public function _onItemError(_arg1:ErrorEvent):void{
            var _local2:LoadingItem = (_arg1.target as LoadingItem);
            this._removeFromConnections(_local2);
            this.log(((("After " + _local2.numTries) + " I am giving up on ") + _local2.url.url), LOG_ERRORS);
            this.log("Error loading", _local2, _arg1.text, LOG_ERRORS);
            this._loadNext();
            dispatchEvent(_arg1);
        }
        public function pauseAll():void{
            var _local1:LoadingItem;
            for each (_local1 in this._items) {
                this.pause(_local1);
            };
            this._isRunning = false;
            this._isPaused = true;
            this.log("Stopping all items", LOG_INFO);
        }
        public function _isAllDoneP():Boolean{
            return (this._items.every(function (_arg1:LoadingItem, ... _args):Boolean{
                return (_arg1._isLoaded);
            }));
        }
        public function getNotLoadedItems():Array{
            return (this._items.filter(function (_arg1:LoadingItem, ... _args):Boolean{
                return (!((_arg1.status == LoadingItem.STATUS_FINISHED)));
            }));
        }
        public function getXML(_arg1, _arg2:Boolean=false):XML{
            return (XML(this._getContentAsType(_arg1, XML, _arg2)));
        }
        public function get totalWeight():int{
            return (this._totalWeight);
        }
        public function get itemsLoaded():int{
            return (this._itemsLoaded);
        }
        public function _canOpenConnectioForItem(_arg1:LoadingItem):Boolean{
            if (this._getNumConnections() >= this.numConnections){
                return (false);
            };
            if (this._getNumConnectionsForItem(_arg1) >= this.maxConnectionsPerHost){
                return (false);
            };
            return (true);
        }
        public function getMovieClip(_arg1:String, _arg2:Boolean=false):MovieClip{
            return (MovieClip(this._getContentAsType(_arg1, MovieClip, _arg2)));
        }
        public function getDisplayObjectLoader(_arg1:String, _arg2:Boolean=false):Loader{
            var res:* = null;
            var key:* = _arg1;
            var clearMemory:Boolean = _arg2;
            if (!this._name){
                throw (new Error("[BulkLoader] Cannot use an instance that has been cleared from memory (.clear())"));
            };
            var item:* = (this.get(key) as ImageItem);
            if (!item){
                return (null);
            };
            try {
                res = (item.loader as Loader);
                if (!res){
                    throw (new Error("bad cast"));
                };
                if (clearMemory){
                    this.remove(key);
                    if (!this._isPaused){
                        this._loadNext();
                    };
                };
                return (res);
            } catch(e:Error) {
                log((("Failed to get content with url: '" + key) + "'as type: Loader"), LOG_ERRORS);
            };
            return (null);
        }
        public function get numConnections():int{
            return (this._numConnections);
        }
        public function getStats():String{
            var stats:* = [];
            stats.push("\n************************************");
            stats.push((("All items loaded(" + this.itemsTotal) + ")"));
            stats.push(("Total time(s):       " + this.totalTime));
            stats.push(("Average latency(s):  " + truncateNumber(this.avgLatency)));
            stats.push(("Average speed(kb/s): " + truncateNumber(this.speedAvg)));
            stats.push(("Median speed(kb/s):  " + truncateNumber(this._speedTotal)));
            stats.push(("KiloBytes total:     " + truncateNumber((this.bytesTotal / 0x0400))));
            var itemsInfo:* = this._items.map(function (_arg1:LoadingItem, ... _args):String{
                return (("\t" + _arg1.getStats()));
            });
            stats.push(itemsInfo.join("\n"));
            stats.push("************************************");
            var statsString:* = stats.join("\n");
            this.log(statsString, LOG_VERBOSE);
            return (statsString);
        }
        public function pause(_arg1, _arg2:Boolean=false):Boolean{
            var _local3:LoadingItem = this.get(_arg1);
            if (!_local3){
                return (false);
            };
            if (_local3.status != LoadingItem.STATUS_FINISHED){
                _local3.stop();
            };
            this.log("STOPPED ITEM:", _local3, LOG_INFO);
            var _local4:Boolean = this._removeFromConnections(_local3);
            if (_arg2){
                this._loadNext();
            };
            return (_local4);
        }
        public function getBinary(_arg1, _arg2:Boolean=false):ByteArray{
            return (ByteArray(this._getContentAsType(_arg1, ByteArray, _arg2)));
        }

    }
}//package org.nickro.project.BulkLoad 
